package com.dkm.biz.gl.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import net.sf.json.JSONArray;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.dkm.base.api.annotion.SKGCacheable;
import com.dkm.base.api.constants.RedisConstants;
import com.dkm.biz.gl.domain.EavAttribute;
import com.dkm.biz.gl.persistence.dao.EavAttrRelQueryDao;
import com.dkm.biz.gl.persistence.dao.EavAttributeQueryDao;
import com.dkm.biz.gl.persistence.entity.AttrRangPo;
import com.dkm.biz.gl.persistence.entity.EavAttrOptionPo;
import com.dkm.biz.gl.persistence.entity.EavAttrRelPo;
import com.dkm.biz.gl.persistence.entity.EavAttributePo;
import com.dkm.biz.gl.persistence.entity.EavSetAttrPo;
import com.dkm.biz.gl.persistence.entity.EavSetGroupPo;
import com.dkm.biz.gl.persistence.entity.EavSetPo;
import com.dkm.biz.gl.persistence.entity.EavValueDatetimePo;
import com.dkm.biz.gl.persistence.entity.EavValueDecimalPo;
import com.dkm.biz.gl.persistence.entity.EavValueIntPo;
import com.dkm.biz.gl.persistence.entity.EavValueOptionsPo;
import com.dkm.biz.gl.persistence.entity.EavValueTextPo;
import com.dkm.biz.gl.persistence.entity.EavValueVarcharPo;
import com.dkm.biz.gl.persistence.entity.GlCatePo;
import com.dkm.biz.gl.repository.EavAttrOptionRepository;
import com.dkm.biz.gl.repository.EavAttributeRepository;
import com.dkm.biz.gl.repository.EavSetAttrRepository;
import com.dkm.biz.gl.repository.EavSetGroupRepository;
import com.dkm.biz.gl.repository.EavSetRepository;
import com.dkm.biz.gl.repository.EavValueDatetimeRepository;
import com.dkm.biz.gl.repository.EavValueDecimalRepository;
import com.dkm.biz.gl.repository.EavValueIntRepository;
import com.dkm.biz.gl.repository.EavValueOptionsRepository;
import com.dkm.biz.gl.repository.EavValueTextRepository;
import com.dkm.biz.gl.repository.EavValueVarcharRepository;
import com.dkm.biz.gl.repository.GlCateRepository;
import com.dkm.biz.gl.service.EavAttrService;
@Service
public class EavAttrServiceImpl implements EavAttrService {
	@Resource	
	EavAttributeQueryDao eavAttributeQueryDao;
	@Resource
	EavAttrOptionRepository eavAttrOptionRepository;
	@Resource
	EavAttrRelQueryDao eavAttrRelQueryDao;
	@Resource
	 EavValueVarcharRepository eavValueVarcharRepository;
	@Resource
	EavValueIntRepository eavValueIntRepository;
	@Resource
	EavValueDecimalRepository eavValueDecimalRepository;
	@Resource
	EavValueDatetimeRepository eavValueDatetimeRepository;
	@Resource
	EavValueTextRepository eavValueTextRepository;
	@Resource
	EavValueOptionsRepository eavValueOptionsRepository;
	@Resource
	EavSetRepository eavSetRepository;
	@Resource
	EavSetGroupRepository eavSetGroupRepository;
	@Resource
	EavSetAttrRepository eavSetAttrRepository;
	@Resource
	GlCateRepository glCateRepository;
	@Resource
	EavAttributeRepository eavAttributeRepository;
	private transient static Log	logger			= LogFactory.getLog(EavAttrServiceImpl.class);
	/**
	 * 根据分类类型, 属性业务键获取对应的属性值
	 * @param eavAttributePo
	 * @param prodId
	 * @return 
	 */
	@SKGCacheable(db=RedisConstants.EAV,key="getAttrValuesByCateKeyAttr_${cateKey}_${attrKey}",params="cateKey,attrKey")
	public  String getAttrValuesByCateKeyAttr(String cateKey,String attrKey)
	{
		 List<AttrRangPo> attrRangPos = new ArrayList<AttrRangPo>();
		 if(!StringUtils.isEmpty(cateKey)&&!StringUtils.isEmpty(attrKey)) {
			 String glCateId="";
			 String attrId="";
			 //first find type rel po
			 //根据分类的业务类型查找分类id
			 GlCatePo glCatePo= glCateRepository.findCatePoByKey(cateKey,null,null,null);
			 if(glCatePo!=null) glCateId=glCatePo.getId();
			 if(!StringUtils.isEmpty(glCateId)){
				 //根据attrKey获取attrId
				 EavAttributePo eavAttributePo = eavAttributeRepository.findEavAttributePoByKey(attrKey);
				 if(eavAttributePo!=null){
					 attrId = eavAttributePo.getId();
					 if(!StringUtils.isEmpty(attrId)){
						 getAttrValueByProdId(eavAttributePo,glCateId);
						if(!StringUtils.isEmpty(eavAttributePo.getAttrValue())){
								 String[] rangList = eavAttributePo.getAttrValue().split(",");
								 for(int i=0;i<rangList.length;i++){
									 String[] values = rangList[i].split("~");
									 AttrRangPo attrRangPo = new AttrRangPo();
									 attrRangPo.setAttrMin(values[0]);
									 attrRangPo.setAttrMax(values[1]);
									 attrRangPos.add(attrRangPo);
								 }
								 Collections.sort(attrRangPos,new Comparator<AttrRangPo>(){
									   public int compare(AttrRangPo o1, AttrRangPo o2) {
										   if(o1==null)return -1;
										   if (o1.getAttrMin() > o2.getAttrMin()) {
											   return 1;
											  } else if (o1.getAttrMin() == o2.getAttrMin()) {
											   return 0;
											  } else {
											   return -1;
											  }
									    }
									});
							}			 
					 }	 
				 } 
			 }
		 }
		 return  JSONArray.fromObject(attrRangPos).toString();
	}
	/**
	 * 根据prodId, 属性集获取所有的属性值
	 * @param eavAttributePo
	 * @param prodId
	 * @return 
	 */
	@SKGCacheable(db=RedisConstants.EAV,key="getAttrValuesByProdSetKey_${prodId}_${eavSetKey}",params="prodId,eavSetKey")
	public Map<String,Object> getAttrValuesByProdSetKey(String prodId,String eavSetKey)
	{
		 Map<String,Object> attrValuesMap = new HashMap<String,Object>();
		 if(!StringUtils.isEmpty(prodId)&&!StringUtils.isEmpty(eavSetKey)){
			 EavSetPo eavSetPo = eavSetRepository.findBySetKey(eavSetKey);
			 if(eavSetPo!=null){
				 List<EavSetGroupPo> eavSetGroupPoList =  eavSetGroupRepository.findBySetId(eavSetPo.getId());
				 List<EavSetAttrPo> eavSetAttrPoList = eavSetAttrRepository.findBySetId(eavSetPo.getId());
				 List<String> attrIds = getAttrIds(eavSetAttrPoList);
				 List<EavAttributePo> eavAttrPoList = eavAttributeQueryDao.findByIds(attrIds);
				 List<EavSetGroupPo> resultList = new ArrayList<EavSetGroupPo>();
				for(EavSetGroupPo eavSetGroupPo:eavSetGroupPoList ){
					 for(EavSetAttrPo eavSetAttrPo: eavSetAttrPoList){
						 if(eavSetGroupPo.getId().equals(eavSetAttrPo.getGroupId())){
							 //获取attr
							 for(EavAttributePo eavAttributePo:eavAttrPoList){
								 if(eavSetAttrPo.getAttrId().equals(eavAttributePo.getId())){
										 getAttrValueByProdId(eavAttributePo,prodId);
										 eavSetAttrPo.setEavAttributePo(eavAttributePo);
								 }
							 }
							 eavSetGroupPo.getEavSetAttrPoList().add(eavSetAttrPo);
						 }
					 }
					 resultList.add(eavSetGroupPo);
				 }
				//将resultList转为json
				for(EavSetGroupPo eavSetGroupPo:resultList){
					List<EavSetAttrPo> poEavSetAttrPoLists = eavSetGroupPo.getEavSetAttrPoList();
					for(EavSetAttrPo esap:poEavSetAttrPoLists)
					{
						EavAttributePo eavAttributePo = esap.getEavAttributePo();
						attrValuesMap.put(eavAttributePo.getKey(), eavAttributePo.getAttrValue());
					}
				}
			 }
		 }
	 return attrValuesMap;
	}
	/**
	 * 根据prodId, 属性获取属性对应的值
	 * @param eavAttributePo
	 * @param prodId
	 * @return 
	 */
	public void getAttrValueByProdId(EavAttributePo eavAttributePo,String prodId){
		if(eavAttributePo.getDataType().equals("options")){
			 List<EavAttrOptionPo> eavAttrOptionPoList =  eavAttrOptionRepository.findByAttrId(eavAttributePo.getId());
			 eavAttributePo.setEavAttrOptionPoList(eavAttrOptionPoList);
			 EavValueOptionsPo eavValueOptionsPo = eavValueOptionsRepository.findByProdAttr(prodId,eavAttributePo.getId());
			 if(eavValueOptionsPo!=null){
					 eavAttributePo.setAttrValue(eavValueOptionsPo.getOptionValues());
			 }
		}else if(eavAttributePo.getDataType().equals("varchar")){
				 EavValueVarcharPo eavValueVarcharPo = eavValueVarcharRepository.findByProdAttr(prodId,eavAttributePo.getId());
				 if(eavValueVarcharPo!=null){
					 eavAttributePo.setAttrValue(eavValueVarcharPo.getValue());
				 }
		 }
		 else if(eavAttributePo.getDataType().equals("int")){
				 EavValueIntPo eavValueIntPo =eavValueIntRepository.findByProdAttr(prodId,eavAttributePo.getId());
				 if(eavValueIntPo!=null){
					 eavAttributePo.setAttrValue(eavValueIntPo.getValue()+"");
				 }
		 } else if(eavAttributePo.getDataType().equals("decimal")){
				 EavValueDecimalPo eavValueDecimalPo = eavValueDecimalRepository.findByProdAttr(prodId,eavAttributePo.getId());
				 if(eavValueDecimalPo!=null){
					 eavAttributePo.setAttrValue(eavValueDecimalPo.getValue()+"");
				 }
		 } else if(eavAttributePo.getDataType().equals("datetime")){
				 EavValueDatetimePo eavValueDatetimePo = eavValueDatetimeRepository.findByProdAttr(prodId,eavAttributePo.getId());
				 if(eavValueDatetimePo!=null){
					 SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					 eavAttributePo.setAttrValue(datetimeFormat.format(eavValueDatetimePo.getValue()));
				 }
		 } else if(eavAttributePo.getDataType().equals("text")){
				 EavValueTextPo eavValueTextPo = eavValueTextRepository.findByProdAttr(prodId,eavAttributePo.getId());
				 if(eavValueTextPo!=null){
					 eavAttributePo.setAttrValue(eavValueTextPo.getValue());
				 }
			 }
		}
		
	/**
	 * 根据prodId, attrId获取属性对应的值
	 * @param eavAttributePo
	 * @param prodId
	 * @return EavAttributePo
	 */
	public EavAttributePo getAttrValuesByProdAttr(String prodId,String attrId){
		//get EavattributePo
		EavAttributePo eavAttributePo = new EavAttributePo();
		EavAttribute eavAttribute = eavAttributeRepository.load(attrId);
		if(eavAttribute!=null)eavAttributePo=eavAttribute.getData();
		getAttrValueByProdId(eavAttributePo,prodId);
		return eavAttributePo;
		}
	
	/**
	 * 根据prodId, 属性集获取该产品所有属性对应的值，以map方式返回(带有默认值）
	 * @param eavAttributePo
	 * @param prodId
	 * @return attrValuesMap
	 */
	public Map<String,Object> getAttrValuesByProdSetKeyWithDefaultMap(String prodId,String eavSetKey){
		List<EavSetGroupPo> resultList =getByProdSetKeyWithDefault(prodId, eavSetKey);
		Map<String,Object> attrValuesMap = new HashMap<String,Object>();
		for(EavSetGroupPo eavSetGroupPo:resultList){
			List<EavSetAttrPo> poEavSetAttrPoLists = eavSetGroupPo.getEavSetAttrPoList();
			for(EavSetAttrPo esap:poEavSetAttrPoLists)
			{
				EavAttributePo eavAttributePo = esap.getEavAttributePo();
				attrValuesMap.put(eavAttributePo.getKey(), eavAttributePo.getAttrValue());
			}
		}
		 return attrValuesMap;
	} 
	/**
	 * 根据prodId, 属性集获取该产品所有属性对应的值，以JSON方式返回(带有默认值）
	 * @param eavAttributePo
	 * @param prodId
	 * @return String
	 */
	 public String genEavAttrJson(String prodId,String eavSetKey)
	 {
		 List<EavSetGroupPo> resultList =getByProdSetKeyWithDefault(prodId, eavSetKey);
		 //将resultList转为json
		String eavAttrJson = JSONArray.fromObject(resultList).toString();
		return eavAttrJson;
	 }
	
	
	

	
		/**
		 * 根据prodId, 直连类型获取该产品所有属性对应的值，以JSON方式返回(带有默认值）
		 * @param eavAttributePo
		 * @param prodId
		 * @return String
		 */
	 public String genEavAttrRelJson(String entityId,String typeKey){
		 //return eavAttributePoList
		 String eavAttrRelJson = "[]";
		 if(!StringUtils.isEmpty(typeKey)){
			 Map<String,Object> params = new HashMap<String,Object>();
			 params.put("whereSql", "type_key_='"+typeKey+"'");
			 params.put("orderBySql", " sort_ ASC");
			 List<EavAttrRelPo> eavAttrRelPos =  eavAttrRelQueryDao.findAll(params);
			 List<EavAttributePo> eavAttributePos = new ArrayList<EavAttributePo>();
			 for(EavAttrRelPo eavAttrRelPo:eavAttrRelPos){
				 EavAttributePo eavAttributePo = eavAttributeQueryDao.get(eavAttrRelPo.getAttrId());
				 eavAttributePo.setAttrValue(eavAttributePo.getDefaultValue());
				 getAttrValueByProdId(eavAttributePo, entityId);
				 eavAttributePo.setCtrlId("attr_"+eavAttributePo.getId());
				 eavAttributePos.add(eavAttributePo);
			 }
			 eavAttrRelJson = JSONArray.fromObject(eavAttributePos).toString();
		 }
		 return eavAttrRelJson;
	 }
	 /**
		 * 根据所有的属性集获取所有属性ID
		 * @param eavSetAttrPoList
		 * @return attrIds
		 */
	private List<String> getAttrIds(List<EavSetAttrPo> eavSetAttrPoList){
		 List<String> attrIds = new ArrayList<String>();
		 for(EavSetAttrPo eavSetAttrPo:eavSetAttrPoList){
				if(attrIds.contains(eavSetAttrPo.getAttrId())){
					continue;
				}else{
					attrIds.add(eavSetAttrPo.getAttrId());
				}
			}
		return attrIds;
	}
	 /**
	 * 根据产品，属性集获取所有的属性分组以及带有默认值的属性值
	 * @param eavSetAttrPoList
	 * @return attrIds
	 */
	public  List<EavSetGroupPo> getByProdSetKeyWithDefault(String prodId,String eavSetKey){
		 List<EavSetGroupPo> resultList = new ArrayList<EavSetGroupPo>();
		 if(!StringUtils.isEmpty(eavSetKey)) {
			 EavSetPo eavSetPo = eavSetRepository.findBySetKey(eavSetKey);
			 if(eavSetPo!=null){
				 List<EavSetGroupPo> eavSetGroupPoList =  eavSetGroupRepository.findBySetId(eavSetPo.getId());
				 List<EavSetAttrPo> eavSetAttrPoList = eavSetAttrRepository.findBySetId(eavSetPo.getId());
				 List<String> attrIds = getAttrIds(eavSetAttrPoList);
				 List<EavAttributePo> eavAttrPoList = eavAttributeQueryDao.findByIds(attrIds);
				for(EavSetGroupPo eavSetGroupPo:eavSetGroupPoList ){
					 for(EavSetAttrPo eavSetAttrPo: eavSetAttrPoList){
						 if(eavSetGroupPo.getId().equals(eavSetAttrPo.getGroupId())){
							 //获取attr
							 for(EavAttributePo eavAttributePo:eavAttrPoList){
								 if(eavSetAttrPo.getAttrId().equals(eavAttributePo.getId())){
									 eavAttributePo.setCtrlId("attr_"+eavSetAttrPo.getAttrId());
									 eavAttributePo.setAttrValue(eavAttributePo.getDefaultValue());
									 if(!StringUtils.isEmpty(eavAttributePo.getDefaultValue())){
										 if(eavAttributePo.getDataType().equals("int")){
											 String[] defaultValue = eavAttributePo.getDefaultValue().split("~");
											 if(defaultValue!=null&&defaultValue.length>1)
											 {
												 eavAttributePo.setAttrValue(genRandom(Integer.parseInt(defaultValue[0]),Integer.parseInt(defaultValue[1]))+"");
											 }
										 }
									 }
									 //若是options，则加载选项
									 if(eavAttributePo.getDataType().equals("options")){
										 List<EavAttrOptionPo> eavAttrOptionPoList =  eavAttrOptionRepository.findByAttrId(eavAttributePo.getId());
										 eavAttributePo.setEavAttrOptionPoList(eavAttrOptionPoList);
									 }
									 if(!StringUtils.isEmpty(prodId)){
										 getAttrValueByProdId(eavAttributePo, prodId);	 
									 }
									 eavSetAttrPo.setEavAttributePo(eavAttributePo);
									 }
								 }
							 eavSetGroupPo.getEavSetAttrPoList().add(eavSetAttrPo);
							 }
							
						 }
					 resultList.add(eavSetGroupPo);
					 }
			 }
		}
		 return resultList;
	}
	
	private int genRandom(Integer minInt,Integer maxInt){
		int count = maxInt-minInt+1;
		Random random = new Random();
		int randNum =(Math.abs(random.nextInt(maxInt)))%count+minInt;
		return randNum;
	}
	
	@SKGCacheable(db=RedisConstants.EAV,key="getAttrValuesNoSkuByProdSetKey_${prodId}_${eavSetKey}",params="prodId,eavSetKey")
	public Map<String,Object> getAttrValuesNoSkuByProdSetKey(String prodId,String eavSetKey)
	{
		 Map<String,Object> attrValuesMap = new HashMap<String,Object>();
		 if(!StringUtils.isEmpty(prodId)&&!StringUtils.isEmpty(eavSetKey)){
			 EavSetPo eavSetPo = eavSetRepository.findBySetKey(eavSetKey);
			 if(eavSetPo!=null){
				 List<EavSetGroupPo> eavSetGroupPoList =  eavSetGroupRepository.findBySetId(eavSetPo.getId());
				 List<EavSetAttrPo> eavSetAttrPoList = eavSetAttrRepository.findBySetIdNoSku(eavSetPo.getId());
				 List<String> attrIds = getAttrIds(eavSetAttrPoList);
				 List<EavAttributePo> eavAttrPoList = eavAttributeQueryDao.findByIds(attrIds);
				 List<EavSetGroupPo> resultList = new ArrayList<EavSetGroupPo>();
				for(EavSetGroupPo eavSetGroupPo:eavSetGroupPoList ){
					 for(EavSetAttrPo eavSetAttrPo: eavSetAttrPoList){
						 if(eavSetGroupPo.getId().equals(eavSetAttrPo.getGroupId())){
							 //获取attr
							 for(EavAttributePo eavAttributePo:eavAttrPoList){
								 if(eavSetAttrPo.getAttrId().equals(eavAttributePo.getId())){
										 getAttrValueByProdId(eavAttributePo,prodId);
										 eavSetAttrPo.setEavAttributePo(eavAttributePo);
								 }
							 }
							 eavSetGroupPo.getEavSetAttrPoList().add(eavSetAttrPo);
						 }
					 }
					 resultList.add(eavSetGroupPo);
				 }
				//将resultList转为json
				for(EavSetGroupPo eavSetGroupPo:resultList){
					List<EavSetAttrPo> poEavSetAttrPoLists = eavSetGroupPo.getEavSetAttrPoList();
					for(EavSetAttrPo esap:poEavSetAttrPoLists)
					{
						EavAttributePo eavAttributePo = esap.getEavAttributePo();
						attrValuesMap.put(eavAttributePo.getKey(), eavAttributePo.getAttrValue());
					}
				}
			 }
		 }
	 return attrValuesMap;
	}
	@Override
	public List<EavSetGroupPo> getAttrNoSkuByProdSetKey(String prodId,
			String eavSetKey) {
		 List<EavSetGroupPo> resultList = new ArrayList<EavSetGroupPo>();
		 if(!StringUtils.isEmpty(prodId)&&!StringUtils.isEmpty(eavSetKey)){
			 EavSetPo eavSetPo = eavSetRepository.findBySetKey(eavSetKey);
			 if(eavSetPo!=null){
				 List<EavSetGroupPo> eavSetGroupPoList =  eavSetGroupRepository.findBySetId(eavSetPo.getId());
				 List<EavSetAttrPo> eavSetAttrPoList = eavSetAttrRepository.findBySetIdNoSku(eavSetPo.getId());
				 List<String> attrIds = getAttrIds(eavSetAttrPoList);
				 List<EavAttributePo> eavAttrPoList = eavAttributeQueryDao.findByIds(attrIds);
				
				for(EavSetGroupPo eavSetGroupPo:eavSetGroupPoList ){
					 for(EavSetAttrPo eavSetAttrPo: eavSetAttrPoList){
						 if(eavSetGroupPo.getId().equals(eavSetAttrPo.getGroupId())){
							 //获取attr
							 for(EavAttributePo eavAttributePo:eavAttrPoList){
								 if(eavSetAttrPo.getAttrId().equals(eavAttributePo.getId())){
										 getAttrValueByProdId(eavAttributePo,prodId);
										 eavSetAttrPo.setEavAttributePo(eavAttributePo);
								 }
							 }
							 eavSetGroupPo.getEavSetAttrPoList().add(eavSetAttrPo);
						 }
					 }
					 resultList.add(eavSetGroupPo);
				 }
			 }
		 }
	 return resultList;
	}

}
